package com.reider.log4AS3
{
	import com.reider.log4AS3.core.log_internal;
	import com.reider.log4AS3.dataholder.Level;
	import com.reider.log4AS3.dataholder.LevelHolder;
	import com.reider.log4AS3.dataholder.Log;
	import com.reider.log4AS3.interfaces.ILogger;
	import com.reider.log4AS3.interfaces.ILoggerContext;
	import com.reider.log4AS3.manager.LogManager;
	
	/**
	 * The Logger class can be used to send log messages to the logging framework.
	 * You can create a Logger by calling <code>LoggerFactory.getLogger(Class)</code>
	 */
	
	public class Logger implements ILogger
	{
		private var loggerContext:ILoggerContext
		
		private var _name:String
		private var _currentLevel:Level = LevelHolder.ALL
		
		//--------------------------------------------------------------------------
		//
		//  Geters, Seters
		//
		//--------------------------------------------------------------------------
		
		public function get name():String
		{
			return _name;
		}

		public function get debugEnabled():Boolean
		{
			return LevelHolder.DEBUG.check( ">=" , currentLevel )
		}
		
		public function get infoEnabled():Boolean
		{
			return LevelHolder.INFO.check( ">=" , currentLevel )
		}
		
		public function get warnEnabled():Boolean
		{
			return LevelHolder.WARN.check( ">=" , currentLevel )
		}
		
		public function get errorEnabled():Boolean
		{
			return LevelHolder.ERROR.check( ">=" , currentLevel )
		}
		
		public function get fatalEnabled():Boolean
		{
			return LevelHolder.FATAL.check( ">=" , currentLevel )
		}
			
		//--------------------------------------------------------------------------
		// currentLevel
		//--------------------------------------------------------------------------

		public function get currentLevel():Level
		{
			return _currentLevel;
		}
		
		public function set currentLevel(value:Level):void
		{
			if(value != null && value != currentLevel){
				_currentLevel = value;
			}
		}
		
		//--------------------------------------------------------------------------
	    //
	    //  Constructor
	    //
	    //--------------------------------------------------------------------------
		
		/**
		 * @private
		 * 
		 */
		
		public function Logger(name:String, loggerContext:ILoggerContext)
		{
			_name = name;
			this.loggerContext = loggerContext
		}
		
		//--------------------------------------------------------------------------
		//
		//  Public Methods
		//
		//--------------------------------------------------------------------------

		public function isLevelEnabled(level:Level):Boolean
		{
			if(level == null) throw new ArgumentError("level can't be null")
			
			return level.check( ">=", currentLevel )
		}
		
	    /**
	    * Sends a debug level log
	    * 
	    * @param format The log message
	    * @param args Additional arguments
	    */
		
		public function debug(format:String, ... args:Array):void
		{
			addLog(LevelHolder.DEBUG, format, args)
		}
		
		/**
	    * Sends an info level log
	    * 
	    * @param format The log message
	    * @param args Additional arguments
	    */
		
		public function info(format:String, ... args:Array):void
		{
			addLog(LevelHolder.INFO, format, args)
		}
		
		/**
	    * Sends a warn level log
	    * 
	    * @param format The log message
	    * @param args Additional arguments
	    */
		
		public function warn(format:String, ... args:Array):void
		{
			addLog(LevelHolder.WARN, format, args)
		}
		
		/**
	    * Sends an error level log
	    * 
	    * @param format The log message
	    * @param args Additional arguments
	    */
		
		public function error(format:String, ... args:Array):void
		{				
			addLog(LevelHolder.ERROR, format, args)
		}
		
		/**
	    * Sends a fatal level log
	    * 
	    * @param format The log message
	    * @param args Additional arguments
	    */
		
		public function fatal(format:String, ... args:Array):void
		{	
			addLog(LevelHolder.FATAL, format, args)
		}
		
		/**
	    * Sends a custom level log
	    * 
	    * @param level The level of the log
	    * @param format The log message
	    * @param args Additional arguments
	    */
		
		public function addLog(level:Level, format:String, ...args:Array):void
		{
			if(!isLevelEnabled(level)) return;
			
			var log:Log = new Log()
			log.log_internal::level = level
			log.log_internal::loggerName = name
			log.log_internal::format = format
				
			if(args.length && args[0] is Array){	
				log.log_internal::args = args[0]
			}else{
				log.log_internal::args = args
			}
			
			loggerContext.addLog(log)
		}
	}
}